using dnAnalytics.Math;
using NUnit.Framework;

namespace dnAnalytics.Tests.Math
{
    [TestFixture]
    public class ComplexMathTest
    {
        [Test]
        public void Conjugate()
        {
            Complex z1 = new Complex(1.1, -2.2);
            Complex z2 = new Complex(0, -2.2);
            Complex z3 = new Complex(1.1, 0);
            Complex z4 = new Complex(-1.1, 2.2);
            Assert.AreEqual(ComplexMath.Conjugate(z1), new Complex(1.1, 2.2));
            Assert.AreEqual(ComplexMath.Conjugate(z2), new Complex(0, 2.2));
            Assert.AreEqual(ComplexMath.Conjugate(z3), new Complex(1.1, 0));
            Assert.AreEqual(ComplexMath.Conjugate(z4), new Complex(-1.1, -2.2));
        }

        [Test]
        public void Max()
        {
            Complex z1 = new Complex(1.1, -2.2);
            Complex z2 = new Complex(0, -2.2);
            Complex zt = ComplexMath.Max(z1, z2);
            Assert.AreEqual(z1, zt);
        }

        [Test]
        public void Norm()
        {
            Complex z1 = new Complex(1.1, -2.2);
            Complex z2 = new Complex(0, -2.2);
            Complex z3 = new Complex(1.1, 0);
            Complex z4 = new Complex(-1.1, 2.2);
            Assert.AreEqual(ComplexMath.Norm(z1), 2.45967477524977, Constants.AcceptableError);
            Assert.AreEqual(ComplexMath.Norm(z2), 2.2, Constants.AcceptableError);
            Assert.AreEqual(ComplexMath.Norm(z3), 1.1, Constants.AcceptableError);
            Assert.AreEqual(ComplexMath.Norm(z4), 2.45967477524977, Constants.AcceptableError);
        }

        [Test]
        public void Polar()
        {
            Complex z1 = new Complex(1.1, -2.2);
            Complex z2 = new Complex(0, -2.2);
            Complex z3 = new Complex(1.1, 0);
            Complex z4 = new Complex(-1.1, 2.2);
            Complex zt = ComplexMath.Polar(z1);
            Assert.AreEqual(zt.Real, 2.45967477524977, Constants.AcceptableError);
            Assert.AreEqual(zt.Imaginary, -1.10714871779409, Constants.AcceptableError);
            zt = ComplexMath.Polar(z2);
            Assert.AreEqual(zt.Real, 2.2, Constants.AcceptableError);
            Assert.AreEqual(zt.Imaginary, -1.5707963267949, Constants.AcceptableError);
            zt = ComplexMath.Polar(z3);
            Assert.AreEqual(zt.Real, 1.1, Constants.AcceptableError);
            Assert.AreEqual(zt.Imaginary, 0, Constants.AcceptableError);
            zt = ComplexMath.Polar(z4);
            Assert.AreEqual(zt.Real, 2.45967477524977, Constants.AcceptableError);
            Assert.AreEqual(zt.Imaginary, 2.0344439357957, Constants.AcceptableError);
        }


        [Test]
        public void Conjugate32()
        {
            Complex32 z1 = new Complex32(1.1f, -2.2f);
            Complex32 z2 = new Complex32(0f, -2.2f);
            Complex32 z3 = new Complex32(1.1f, 0f);
            Complex32 z4 = new Complex32(-1.1f, 2.2f);
            Assert.AreEqual(ComplexMath.Conjugate(z1), new Complex32(1.1f, 2.2f));
            Assert.AreEqual(ComplexMath.Conjugate(z2), new Complex32(0f, 2.2f));
            Assert.AreEqual(ComplexMath.Conjugate(z3), new Complex32(1.1f, 0f));
            Assert.AreEqual(ComplexMath.Conjugate(z4), new Complex32(-1.1f, -2.2f));
        }

        [Test]
        public void Max32()
        {
            Complex32 z1 = new Complex32(1.1f, -2.2f);
            Complex32 z2 = new Complex32(0f, -2.2f);
            Complex32 zt = ComplexMath.Max(z1, z2);
            Assert.AreEqual(z1, zt);
        }

        [Test]
        public void Norm32()
        {
            Complex32 z1 = new Complex32(1.1f, -2.2f);
            Complex32 z2 = new Complex32(0f, -2.2f);
            Complex32 z3 = new Complex32(1.1f, 0f);
            Complex32 z4 = new Complex32(-1.1f, 2.2f);
            Assert.AreEqual(ComplexMath.Norm(z1), 2.45967477524977, Constants.AcceptableError32);
            Assert.AreEqual(ComplexMath.Norm(z2), 2.2, Constants.AcceptableError32);
            Assert.AreEqual(ComplexMath.Norm(z3), 1.1, Constants.AcceptableError32);
            Assert.AreEqual(ComplexMath.Norm(z4), 2.45967477524977, Constants.AcceptableError32);
        }

        [Test]
        public void Polar32()
        {
            Complex32 z1 = new Complex32(1.1f, -2.2f);
            Complex32 z2 = new Complex32(0f, -2.2f);
            Complex32 z3 = new Complex32(1.1f, 0f);
            Complex32 z4 = new Complex32(-1.1f, 2.2f);
            Complex32 zt = ComplexMath.Polar(z1);
            Assert.AreEqual(zt.Real, 2.45967477524977, Constants.AcceptableError32);
            Assert.AreEqual(zt.Imaginary, -1.10714871779409, Constants.AcceptableError32);
            zt = ComplexMath.Polar(z2);
            Assert.AreEqual(zt.Real, 2.2, Constants.AcceptableError32);
            Assert.AreEqual(zt.Imaginary, -1.5707963267949, Constants.AcceptableError32);
            zt = ComplexMath.Polar(z3);
            Assert.AreEqual(zt.Real, 1.1, Constants.AcceptableError32);
            Assert.AreEqual(zt.Imaginary, 0, Constants.AcceptableError32);
            zt = ComplexMath.Polar(z4);
            Assert.AreEqual(zt.Real, 2.45967477524977, Constants.AcceptableError32);
            Assert.AreEqual(zt.Imaginary, 2.0344439357957, Constants.AcceptableError32);
        }

        [Test]
        public void MinTest()
        {
            Complex a = new Complex(0, 0);
            Complex b = new Complex(1, 1);
            Assert.AreEqual(a, ComplexMath.Min(a, b));

            a = new Complex(1, 1);
            b = new Complex(-1, -1);
            Assert.AreEqual(a, ComplexMath.Min(a, b));

            a = new Complex(0, 1);
            b = new Complex(-1, -1);
            Assert.AreEqual(a, ComplexMath.Min(a, b));

            a = new Complex(2, 2);
            b = new Complex(1, -1);
            Assert.AreEqual(b, ComplexMath.Min(a, b));

            Complex32 c = new Complex32(0, 0);
            Complex32 d = new Complex32(1, 1);
            Assert.AreEqual(c, ComplexMath.Min(c, d));

            c = new Complex32(1, 1);
            d = new Complex32(-1, -1);
            Assert.AreEqual(c, ComplexMath.Min(c, d));

            c = new Complex32(0, 1);
            d = new Complex32(-1, -1);
            Assert.AreEqual(c, ComplexMath.Min(c, d));

            c = new Complex32(2, 2);
            d = new Complex32(1, -1);
            Assert.AreEqual(d, ComplexMath.Min(c, d));

        }
    }
}
